#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <pthread.h>
#include <unistd.h>

using namespace std;

// int g_val = 100;
__thread int g_val = 100;// 添加__thread关键字，可以定义出一个线程局部存储变量。

string transformTID(const pthread_t& thread_id)
{
    char tid[128];
    snprintf(tid, sizeof(tid), "0x%x", thread_id);

    return tid;
}

void *start_routine(void *args)
{
    string threadname = static_cast<const char *>(args);// 告诉编译器是在已知情况下，进行的强制类型转换，不要报warning
    // pthread_detach(pthread_self());// 线程设置自己为分离状态

    int cnt = 5;
    while (true)
    {
        cout << threadname << " running... , tid:" << transformTID(pthread_self()) << " g_val:" << g_val << " &g_val: " << &g_val << endl;
        sleep(1);
        g_val++;
    }
    
    return nullptr;
}
int main()
{
    // pthread_attr_t;//线程属性

    pthread_t tid;
    pthread_create(&tid, nullptr, start_routine, (void*)"thread 1");

    pthread_detach(tid);//所以更加推荐的做法是: 在创建线程之后，紧接着就设置线程为分离状态。这样就不用主动sleep主线程了，这样的方式实在挫

    string main_id = transformTID(pthread_self());
    cout << "main thread running ... , new thread id : " << transformTID(tid) << " main thread id:" << main_id << endl;

    // sleep(3);//在主线程join()之前，一定要保证主线程知道新线程是分离状态

    //一个线程默认是joinable的，如果设置了分离状态，则不能进行等待了！
    // int retnum = pthread_join(tid, nullptr);// 新线程死循环没有退出，那么主线程就会在这里阻塞式等待，同样也不会退出。
    // cout << "result: " << retnum << " " << strerror(retnum) << endl;


    // 新线程设置为分离状态后，主线程就不用再等新线程了(不用显示的调用join()了)，新线程运行完自动会被回收掉，再也不用担心资源泄露了！
    while(true)
    {
        cout << "main thread running ... , new thread id : " << transformTID(tid) << " main thread id:" \
        << main_id << " g_val:" << g_val << " &g_val: " << &g_val << endl;
        sleep(1);
    }

    
    return 0;
}